package com.hctg.forced2sleep.utils;

import android.app.ActivityManager;
import android.app.usage.ConfigurationStats;
import android.app.usage.EventStats;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.actor.myandroidframework.utils.ConfigUtils;
import com.actor.myandroidframework.utils.LogUtils;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;

import java.util.Calendar;
import java.util.List;
import java.util.Map;

/**
 * description: App使用情况工具类 <br />
 * <a href="https://blog.csdn.net/fromVillageCoolBoy/article/details/135355449" target="_blank">Android 应用使用数据统计服务——UsageStatsManager-CSDN博客.html</a> <br />
 * <a href="https://www.jianshu.com/p/a513accd40cd" target="_blank">4种获取前台应用的方法（肯定有你不知道的） - 简书.html</a> <br />
 * <br />
 * {@link null 注意:} 使用前, 需要先声明权限
 * <pre>
 *     &lt;!-- 允许程序获取当前或最近运行的应用(在api21及以上, 这个权限已经过时了) -->
 *     &lt;uses-permission android:name="android.permission.GET_TASKS" /&gt;
 *     &lt;uses-permission
 *         android:name="android.permission.PACKAGE_USAGE_STATS"
 *         tools:ignore="ProtectedPermissions" /&gt;
 * </pre>
 *
 * @author : ldf
 */
public class UsageStatsUtils {

    protected static UsageStatsManager usageStatsManager;
    protected static String processPackageName = null;
    protected static String processClassName = null;

    public static UsageStatsManager getUsageStatsManager() {
        if (usageStatsManager == null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                usageStatsManager = (UsageStatsManager) ConfigUtils.APPLICATION.getSystemService(Context.USAGE_STATS_SERVICE);
            }
        }
        return usageStatsManager;
    }

    /**
     * 查询今日使用情况 <br />
     * {@link UsageStats#getLastTimeStamp()} 获取指定时间区间内这个事件最后一次发生的时间戳 <br />
     * {@link UsageStats#getLastTimeForegroundServiceUsed()} <br />
     * {@link UsageStats#getLastTimeUsed()} 获取应用最后一次使用时间戳 <br />
     * {@link UsageStats#getLastTimeVisible()}
     */
    @Nullable
    public static List<UsageStats> getTodayUsage() {
        Calendar calendar = Calendar.getInstance();
        long now = calendar.getTimeInMillis();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return queryUsage(UsageStatsManager.INTERVAL_DAILY, calendar.getTimeInMillis(), now);
    }

    /**
     * 查询使用情况. if(endTime - beginTime)这段时间内不切换页面, 就没有状态改变, 就会返回空的List <br />
     * 注意:从Android R(Android 11.0, Api 30)开始，如果用户的设备不是处于解锁状态(由UserManager.isUserUnlocked()定义)，那么将返回null。
     * @param intervalType 间隔类型, 例: UsageStatsManager.INTERVAL_DAILY
     * @param beginTime 开始时间
     * @param endTime 结束时间
     */
    @Nullable
    public static List<UsageStats> queryUsage(int intervalType, long beginTime, long endTime) {
        UsageStatsManager usageStatsManager = getUsageStatsManager();
        if (usageStatsManager == null) return null;
        return usageStatsManager.queryUsageStats(intervalType, beginTime, endTime);
    }

    /**
     * 查询设备全局应用给定范围内的所有统计数据(使用该范围的最佳间隔)
     * @return Map: key是包名, value是使用情况
     */
    @Nullable
    public static Map<String, UsageStats> queryAndAggregateUsageStats(long beginTime, long endTime) {
        UsageStatsManager usageStatsManager = getUsageStatsManager();
        if (usageStatsManager == null) return null;
        return usageStatsManager.queryAndAggregateUsageStats(beginTime, endTime);
    }

    /**
     * 获取当前前台进程.
     * 注意:从Android R(Android 11.0, Api 30)开始，如果用户的设备不是处于解锁状态(由UserManager.isUserUnlocked()定义)，那么将返回null。
     */
    @Nullable
    public static ComponentName getProcessName() {
//        boolean isForeground = AppUtils.isAppForeground("packageName");
//        String foregroundProcessName = ProcessUtils.getForegroundProcessName();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            UsageStatsManager usageStatsManager = getUsageStatsManager();
            if (usageStatsManager == null) return null;
            long end = System.currentTimeMillis();
            UsageEvents queryEvents = usageStatsManager.queryEvents(end - 10_000L, end);
            if (queryEvents == null) return null;
            UsageEvents.Event event = new UsageEvents.Event();
            //if上方的10s内没有页面改变的事件, hasNextEvent()=false
            while (queryEvents.hasNextEvent()) {
                boolean getNextEventSuccess = queryEvents.getNextEvent(event);
                if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
                    processPackageName = event.getPackageName();
                    processClassName = event.getClassName();
//                    LogUtils.errorFormat("getNextEventSuccess=%b, processPackageName=%s, processClassName=%s",
//                            getNextEventSuccess, processPackageName, processClassName);
                }
            }
            //if上方的10s内没有页面改变的事件, 返回上次的页面
            if (processPackageName != null && processClassName != null) {
                return new ComponentName(processPackageName, processClassName);
            }
            return null;
        } else {
            //com.hctg.forced2sleep, com.huawei.android.launcher
//            String foregroundProcessName = ProcessUtils.getForegroundProcessName();
//            LogUtils.errorFormat("foregroundProcessName=%s", foregroundProcessName);
            ActivityManager activityManager = (ActivityManager) ConfigUtils.APPLICATION.getSystemService(Context.ACTIVITY_SERVICE);
            if (activityManager == null) return null;
            List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(1);
            if (runningTasks == null || runningTasks.isEmpty()) return null;
            ActivityManager.RunningTaskInfo runningTaskInfo = runningTasks.get(0);
            if (runningTaskInfo == null) return null;
            //{"mClass":"com.huawei.android.launcher.unihome.UniHomeLauncher","mPackage":"com.huawei.android.launcher"}
            return runningTaskInfo.topActivity;
        }
    }

    /**
     * 查询当前应用的使用事件, Android 9.0(Api 28)
     * 注意:从Android R(Android 11.0, Api 30)开始，如果用户的设备不是处于解锁状态(由UserManager.isUserUnlocked()定义)，那么将返回null。
     */
    @RequiresApi(api = Build.VERSION_CODES.P)
    public static void queryEventsForSelf() {
        UsageStatsManager usageStatsManager = getUsageStatsManager();
        if (usageStatsManager == null) return;
        long end = System.currentTimeMillis();
        UsageEvents usageEvents = usageStatsManager.queryEventsForSelf(end - 10_000L, end);
        if (usageEvents == null) return;
        UsageEvents.Event event = new UsageEvents.Event();
        while (usageEvents.hasNextEvent()) {
            boolean getNextEventSuccess = usageEvents.getNextEvent(event);
            if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
            }
            String processPackageName = event.getPackageName();
            String processClassName = event.getClassName();
            LogUtils.errorFormat("getNextEventSuccess=%b, processPackageName=%s, processClassName=%s",
                    getNextEventSuccess, processPackageName, processClassName);
        }
    }

    /**
     * 获取指定时间区间内硬件配置信息统计数据
     * 注意:从Android R(Android 11.0, Api 30)开始，如果用户的设备不是处于解锁状态(由UserManager.isUserUnlocked()定义)，那么将返回null。
     */
    @Nullable
    public static List<ConfigurationStats> queryConfigurations(int intervalType, long beginTime, long endTime) {
        UsageStatsManager usageStatsManager = getUsageStatsManager();
        if (usageStatsManager == null) return null;
        return usageStatsManager.queryConfigurations(intervalType, beginTime, endTime);
    }

    /**
     * 设备状态事件统计, Android 9.0(Api 28) <br />
     * 锁屏事件、切换前台事件、切换到后台事件、屏幕交互状态事件、屏幕非交互状态事件等 <br />
     * 注意:从Android R(Android 11.0, Api 30)开始，如果用户的设备不是处于解锁状态(由UserManager.isUserUnlocked()定义)，那么将返回null。<br />
     * <br />
     * {@link EventStats#getLastTimeStamp()} 获取指定时间区间内应用最后一次使用时间戳 <br />
     * {@link EventStats#getLastEventTime()} 获取这个事件最后一次发生的时间戳
     */
    @RequiresApi(api = Build.VERSION_CODES.P)
    @Nullable
    public static List<EventStats> queryEventStats(int intervalType, long beginTime, long endTime) {
        UsageStatsManager usageStatsManager = getUsageStatsManager();
        if (usageStatsManager == null) return null;
        return usageStatsManager.queryEventStats(intervalType, beginTime, endTime);
    }

    /**
     * 返回指定的应用程序当前是否处于非活动状态。如果应用在系统定义的一段时间内没有被直接或间接使用，那么就会出现这种情况。
     * 这可能是几个小时或几天的顺序。当设备充电时，应用程序不被认为是不活动的。
     * 调用者查询其他应用的非活动状态, 必须具有android.Manifest.permission.PACKAGE_USAGE_STATS权限才行
     * Android 6.0(Api 23)
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static boolean isAppInactive(@NonNull String packageName) {
        UsageStatsManager usageStatsManager = getUsageStatsManager();
        if (usageStatsManager == null) return false;
        return usageStatsManager.isAppInactive(packageName);
    }

    /**
     * 应用待机分组功能 <br />
     * 根据应用使用情况, 对应用进行不同分组, 从而实施不同的限制策略, 本api用户获取应用处于哪一个分组.
     * StandbyBucket决定了应用程序在运行后台任务(如作业和警报)时将受到多大程度的限制。
     * Android 9.0(Api 28) <br />
     * {@link UsageStatsManager#STANDBY_BUCKET_ACTIVE}      : 应用正在被使用或者经常被使用
     * {@link UsageStatsManager#STANDBY_BUCKET_WORKING_SET} : 应用定期频繁使用
     * {@link UsageStatsManager#STANDBY_BUCKET_FREQUENT}    : 经常使用，但不是每一天
     * {@link UsageStatsManager#STANDBY_BUCKET_RARE}        : 应用很少使用
     * {@link UsageStatsManager#STANDBY_BUCKET_RESTRICTED}  ：有限的，很小的
     */
    @RequiresApi(api = Build.VERSION_CODES.P)
    public static int getAppStandbyBucket() {
        UsageStatsManager usageStatsManager = getUsageStatsManager();
        if (usageStatsManager == null) return UsageStatsManager.STANDBY_BUCKET_RARE;
        return usageStatsManager.getAppStandbyBucket();
    }

    /**
     * 是否有数据量访问的权限
     */
    public static boolean isGranted(Context context) {
        return XXPermissions.isGranted(context, Permission.PACKAGE_USAGE_STATS);
    }

    /**
     * 请求数据量访问的权限
     */
    public static void requestUsageStats(Context context, OnPermissionCallback callback) {
        XXPermissions.with(context)
                .permission(Permission.PACKAGE_USAGE_STATS)
                .request(callback);
    }

    /**
     * 跳转数据量访问的权限
     */
    public static void go2Setting(Context context) {
        XXPermissions.startPermissionActivity(context, Permission.PACKAGE_USAGE_STATS);
        //一样的
//        Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
//        ActivityUtils.startActivity(intent);
    }
}
